package net.kodra.supereasy.authentication.client;

import net.kodra.openid.gwt.AuthenticationService;
import net.kodra.openid.gwt.AuthenticationServiceAsync;
import net.kodra.openid.gwt.widget.AuthenticatedUser;
import net.kodra.openid.gwt.widget.OpenIDSelectorWidget;
import net.kodra.openid.gwt.widget.SelectionEvent;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

public class UserAuthenticationWidget extends Composite
{

  private static UserAuthenticationWidgetUiBinder uiBinder = GWT.create(UserAuthenticationWidgetUiBinder.class);

  interface UserAuthenticationWidgetUiBinder extends UiBinder<Widget, UserAuthenticationWidget>
  {
  }

  /**
   * Create a remote service proxy to talk to the server-side Authentication service.
  **/
  private final AuthenticationServiceAsync authenticationService = GWT.create(AuthenticationService.class);

  @UiField DecoratorPanel userPanel;
  @UiField Label email;
  @UiField Label authDomain;
  @UiField Label userId;
  @UiField Label federatedIdentity;
  @UiField Label nickname;
  @UiField Button logoutButton;

  @UiField DecoratorPanel loginPanel;
  @UiField OpenIDSelectorWidget openIDSelectorWidget;

  public UserAuthenticationWidget(String widgetTitle)
  {
    this();
    logoutButton.setText(widgetTitle);
  }

  public UserAuthenticationWidget()
  {
    initWidget(uiBinder.createAndBindUi(this));

    authenticationService.getCurrentUser(new My1stAsyncCallback());

  }


  String loginURL = null;
  String logoutURL = null;


  @UiHandler("openIDSelectorWidget")
  void onOpenIdSelection(SelectionEvent event)
  {
    Window.alert(event.toString());

    authenticationService.getLoginURL(Window.Location.getPath(), event.getProvider(), new My3rdAsyncCallback());
  }

  @UiHandler("logoutButton")
  void onLogoutButtonClick(ClickEvent event)
  {
    boolean isOK = Window.confirm("should redirect to: " + logoutURL);
    if (isOK)
    {
      Window.Location.replace(logoutURL);
      //Window.open(logoutURL, "Logging out via OpenID", "chrome=yes,modal=yes");
    }
  }

  private class My1stAsyncCallback implements AsyncCallback<AuthenticatedUser>
  {
    @Override
    public void onFailure(Throwable caught)
    {
      // TODO Auto-generated method stub
      Window.alert("My1stAsyncCallback: " + caught.getMessage());
    }

    @Override
    public void onSuccess(AuthenticatedUser authenticatedUser)
    {
      if (authenticatedUser != null)
      {
        email.setText(authenticatedUser.getEmail());
        authDomain.setText(authenticatedUser.getAuthDomain());
        userId.setText(authenticatedUser.getUserId());
        federatedIdentity.setText(authenticatedUser.getFederatedIdentity());
        nickname.setText(authenticatedUser.getNickname());
        nickname.setTitle(authenticatedUser.getAdminFlag() ? "Admin" : "");

        userPanel.setVisible(true);
        loginPanel.setVisible(false);

        logoutButton.setEnabled(false);

        if (authenticatedUser.getAuthDomain().length() > 0)
          authenticationService.getLogoutURL(Window.Location.getPath(), authenticatedUser.getAuthDomain(), new My2ndAsyncCallback());
        else
          authenticationService.getLogoutURL(Window.Location.getPath(), new My2ndAsyncCallback());
      }
      else
      {
        
        userPanel.setVisible(false);
        loginPanel.setVisible(true);
      }
    }
  }


  private class My2ndAsyncCallback implements AsyncCallback<String>
  {
    @Override
    public void onFailure(Throwable caught)
    {
      // TODO Auto-generated method stub
      Window.alert("My2ndAsyncCallback: " + caught.getMessage());
    }

    @Override
    public void onSuccess(String result)
    {
      logoutURL = result;
      logoutButton.setEnabled(true);
    }
  }


  private class My3rdAsyncCallback implements AsyncCallback<String>
  {
    @Override
    public void onFailure(Throwable caught)
    {
      // TODO Auto-generated method stub
      Window.alert("My3rdAsyncCallback: " + caught.getMessage());
    }

    @Override
    public void onSuccess(String result)
    {
      loginURL = result;

      boolean isOK = Window.confirm("should redirect to: " + loginURL);
      if (isOK) //Window.open(loginURL, "Authorisation via OpenID", "chrome=yes,modal=yes");
      {
        Window.Location.replace(loginURL);
        /*
        final DialogBox dialogBox = new DialogBox();
        dialogBox.setGlassEnabled(true);
        dialogBox.setWidth("530px");
        dialogBox.setText("OpenID Authentication");
        dialogBox.setAnimationEnabled(true);
        Frame frame = new Frame(loginURL);
        frame.setWidth("500px");
        dialogBox.setWidget(frame);
        dialogBox.center();
        */
      }
    }
  }

}
